﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<stdlib.h>
#include<assert.h>

//class Time
//{
//public:
//	~Time()
//	{
//		cout << "~Time()" << endl;
//	}
//private:
//	int _hour;
//	int _minute;
//	int _second;
//};
//class Date
//{
//private:
//	// 基本类型(内置类型)
//	int _year = 1970;
//	int _month = 1;
//	int _day = 1;
//	// 自定义类型
//	Time _t;
//};
//int main()
//{
//	Date d;
//	return 0;
//}

//class Date
//{
//public:
//	Date(int year = 1949, int month = 10, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	//Date(const Date d)      // 错误写法：编译报错，会引发无穷递归
//	//Date(const Date& d)       // 正确写法
//	//{
//	//	_year = d._year;
//	//	_month = d._month;
//	//	_day = d._day;
//	//}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	Date d1;
//	Date d2(d1);
//	return 0;
//}

//class Time
//{
//public:
//	Time()
//	{
//		_hour = 1;
//		_minute = 1;
//		_second = 1;
//	}
	/*Time(const Time& t)
	{
		_hour = t._hour;
		_minute = t._minute;
		_second = t._second;
		cout << "Time::Time(const Time&)" << endl;
	}*/
//private:
//	int _hour;
//	int _minute;
//	int _second;
//};
//
//class Date
//{
//private:
//	// 基本类型(内置类型)
//	int _year = 1970;
//	int _month = 1;
//	int _day = 1;
//	// 自定义类型
//	Time _t;
//};
//int main()
//{
//	Date d1;
//
//	// 用已经存在的d1拷贝构造d2，此处会调用Date类的拷贝构造函数
//	// 但Date类并没有显式定义拷贝构造函数，则编译器会给Date类生成一个默认的拷贝构造函数
//	Date d2(d1);
//	return 0;
//}

// 这里会发现下面的程序会崩溃掉？这里就需要我们以后讲的深拷贝去解决。
//typedef int DataType;
//class Stack
//{
//public:
//	Stack(size_t capacity = 10)
//	{
//		_array = (DataType*)malloc(capacity * sizeof(DataType));
//		if (nullptr == _array)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_size = 0;
//		_capacity = capacity;
//	}
//	void Push(const DataType& data)
//	{
//		// CheckCapacity();
//		_array[_size] = data;
//		_size++;
//	}
//	~Stack()
//	{
//		if (_array)
//		{
//			free(_array);
//			_array = nullptr;
//			_capacity = 0;
//			_size = 0;
//		}
//	}
//private:
//	DataType* _array;
//	size_t _size;
//	size_t _capacity;
//};
//
//int main()
//{
//	Stack s1;
//	s1.Push(1);
//	s1.Push(2);
//	s1.Push(3);
//	s1.Push(4);
//	Stack s2(s1);
//	return 0;
//}

//class Date
//{
//public:
//	Date(int year, int minute, int day)
//	{
//		cout << "Date(int,int,int):" << this << endl;
//	}
//	Date(const Date& d)
//	{
//		cout << "Date(const Date& d):" << this << endl;
//	}
//	~Date()
//	{
//		cout << "~Date():" << this << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//Date& Test(Date d)
//{
//	Date temp(d);
//	return temp;
//}
//int main()
//{
//	Date d1(2022, 1, 13);
//	Test(d1);
//	return 0;
//}
class Stack
{
public:
Stack(int capacity = 4)
{
	cout << "Stack()" << endl;

	_a = (int*)malloc(sizeof(int) * capacity);
	if (nullptr == _a)
	{
		perror("malloc申请空间失败");
		return;
	}

	_capacity = capacity;
	_top = 0;
}

// st2(st1)
Stack(const Stack& st)
{
	_a = (int*)malloc(sizeof(int) * st._capacity);
	if (nullptr == _a)
	{
		perror("malloc申请空间失败");
		return;
	}

	memcpy(_a, st._a, sizeof(int) * st._top);
	_top = st._top;
	_capacity = st._capacity;
}

~Stack()
{
	cout << "~Stack()" << endl;
	free(_a);
	_a = nullptr;
	_capacity = _top = 0;
}

private:
	int* _a = nullptr;
	int _top = 0;
	int _capacity;
};

//Stack func()
//{
//	Stack st;
//	return st;
//}

 //错误的
//Stack& func()
//{
//	Stack st;
//	return st;
//}
//
//int main()
//{
//	/*Date d1;
//	func(d1);*/
//
//	Stack st1;
//	//func(st1);
//
//	//func();
//
//	Stack ret = func();
//
//	return 0;
//}

//class Date
//{
//public:
//	Date(int year = 1900, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//
//	Date(const Date& d)
//	{
//		_year = d._year;
//		_month = d._month;
//		_day = d._day;
//	}
//
//	/*Date& operator=(const Date& d)
//	{
//		if (this != &d)
//		{
//			_year = d._year;
//			_month = d._month;
//			_day = d._day;
//		}
//
//		return *this;
//	}*/
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//int main()
//{
//	Date d1;
//	Date d2(1949,10,1);
//	d1 = d2;
//	return 0;
//}

//class Date
//{
//public:
//	Date(int year = 1900, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	int _year;
//	int _month;
//	int _day;
//};
//// 赋值运算符重载成全局函数，注意重载成全局函数时没有this指针了，需要给两个参数
//Date& operator=(Date& left, const Date& right)
//{
//	if (&left != &right)
//	{
//		left._year = right._year;
//		left._month = right._month;
//		left._day = right._day;
//	}
//	return left;
//}
//// 编译失败：
//// error C2801: “operator =”必须是非静态成员

//class Time
//{
//public:
//	Time()
//	{
//		_hour = 1;
//		_minute = 1;
//		_second = 1;
//	}
//	Time& operator=(const Time& t)
//	{
//		if (this != &t)
//		{
//			_hour = t._hour;
//			_minute = t._minute;
//			_second = t._second;
//		}
//		return *this;
//	}
//private:
//	int _hour;
//	int _minute;
//	int _second;
//};
//class Date
//{
//private:
//	// 基本类型(内置类型)
//	int _year = 1970;
//	int _month = 1;
//	int _day = 1;
//	// 自定义类型
//	Time _t;
//};
//int main()
//{
//	Date d1;
//	Date d2;
//	d1 = d2;
//	return 0;
//}

// 这里会发现下面的程序会崩溃掉？这里就需要我们以后讲的深拷贝去解决。
//typedef int DataType;
//class Stack
//{
//public:
//	Stack(size_t capacity = 10)
//	{
//		_array = (DataType*)malloc(capacity * sizeof(DataType));
//		if (nullptr == _array)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_size = 0;
//		_capacity = capacity;
//	}
//	void Push(const DataType& data)
//	{
//		// CheckCapacity();
//		_array[_size] = data;
//		_size++;
//	}
//	~Stack()
//	{
//		if (_array)
//		{
//			free(_array);
//			_array = nullptr;
//			_capacity = 0;
//			_size = 0;
//		}
//	}
//private:
//	DataType* _array;
//	size_t _size;
//	size_t _capacity;
//};
//int main()
//{
//	Stack s1;
//	s1.Push(1);
//	s1.Push(2);
//	s1.Push(3);
//	s1.Push(4);
//	Stack s2;
//	s2 = s1;
//	return 0;
//}
//
//class Date
//{
//public:
//	Date(int year = 1900, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	// 前置++：返回+1之后的结果
//	// 注意：this指向的对象函数结束后不会销毁，故以引用方式返回提高效率
//	Date& operator++()
//	{
//		_day += 1;
//		return *this;
//	}
//	// 后置++：
//	// 前置++和后置++都是一元运算符，为了让前置++与后置++形成能正确重载
//	// C++规定：后置++重载时多增加一个int类型的参数，但调用函数时该参数不用传递，编译器
//	//自动传递
//		// 注意：后置++是先使用后+1，因此需要返回+1之前的旧值，故需在实现时需要先将this保存
//		一份，然后给this + 1
//		//       而temp是临时对象，因此只能以值的方式返回，不能返回引用
//		Date operator++(int)
//	{
//		Date temp(*this);
//		_day += 1;
//		return temp;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	Date d;
//	Date d1(2022, 1, 13);
//	d = d1++;    // d: 2022,1,13   d1:2022,1,14
//	d = ++d1;    // d: 2022,1,15   d1:2022,1,15
//	return 0;
//}

//日期内的实现
class Date
{
public:
	// 全缺省的构造函数
	Date(int year=1, int month=1, int day=1);
	
	// 拷贝构造函数
	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	//获取每个月的天数
	int Geymonthday(int year, int month);

	// 赋值运算符重载
	Date& operator=(const Date& d);

	//运算符重载<
	bool operator<(const Date& x) const;

	//运算符重载==
	bool operator==(const Date& x) const;

	//运算符重载<=
	bool operator<=(const Date& x) const;

	//运算符重载>
	bool operator>(const Date& x) const;

	//运算符重载>=
	bool operator>=(const Date& x) const;

	//运算符重载!=
	bool operator!=(const Date& x) const;

	//日期加天数 例：d1=d1+100;改变d1的值
	Date& operator+=(int day); 

	//日期加天数 例：d1+100；不改变d1的值
	Date operator+(int day) const;

	//日期减天数 例：d1=d1-100;改变d1的值
	Date& operator-=(int day);

	//日期加天数 例：d1-100；不改变d1的值
	Date operator-(int day) const;

	//前置++
	Date& operator++();

	//后置++
	Date operator++(int);

	//前置--
	Date& operator--();
	
	//后置--
	Date operator--(int);

	//两个日期相减返回天数值
	int operator-(const Date& d) const;

private:
	int _year;
	int _month;
	int _day;
};

//获取每个月的天数
int Date::Geymonthday(int year, int month)
{
	int dayarr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
	{
		return 29;
	}
	else
	{
		return dayarr[month];
	}
}

// 全缺省的构造函数
Date::Date(int year, int month, int day)
{
	if (month > 0 && month < 13)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
	{
		cout << "输入非法" << endl;
		assert("false");
	}
}

// 赋值运算符重载
Date& Date::operator=(const Date& d) 
{
	if (this != &d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	return *this;
}

//运算符重载<
bool Date::operator<(const Date& x) const
{
	if (this->_year < x._year)
	{
		return true;
	}
	if (this->_year == x._year && this->_month < x._month)
	{
		return true;
	}
	if (this->_year == x._year && this->_month == x._month && this->_day < x._day)
	{
		return true;
	}
	return false;
}

//运算符重载==
bool Date::operator==(const Date& x) const
{
	return this->_year == x._year && 
		this->_month == x._month && this->_day == x._day;
}

//运算符重载<=
bool Date::operator<=(const Date& x) const
{
	//return operator==(x)||operator<(x);两者都可以
	return *this == x || *this < x;
}

//运算符重载>
bool Date::operator>(const Date& x) const
{
	return !(*this <= x);
}

//运算符重载>=
bool Date::operator>=(const Date& x) const
{
	return !(*this < x);
}

//运算符重载!=
bool Date::operator!=(const Date& x) const
{
	return !(*this == x);
}

//日期加天数
Date& Date::operator+=(int day)
{
	_day += day;
	while (_day>0 && _day > Date::Geymonthday(_year,_month))
	{
		_month++;
		if (_month > 12)
		{
			_month = 1;
			_year++;
		}
		_day -= Date::Geymonthday(_year, _month);
	}
	return *this;
}

//日期加天数 例：d1+100；不改变d1的值
Date Date::operator+(int day) const
{
	Date tmp(*this);
	tmp += 100;
	return tmp;
}

//日期减天数 例：d1=d1-100;改变d1的值
Date& Date::operator-=(int day)
{
	/*int tmp = _day;
	_day = day;
	_month -= 1;
	while (_day > Date::Geymonthday(_year, _month))
	{
		_day -= Date::Geymonthday(_year, _month);
		_month--;
		if (_month < 1)
		{
			_year--;
			_month == 12;
		}
	}
	_day = Date::Geymonthday(_year, _month) - _day;
	*this += tmp;*/
	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			_month = 12;
			--_year;
		}

		_day += Geymonthday(_year, _month);
	}
	return *this;
}

//日期加天数 例：d1-100；不改变d1的值
Date Date::operator-(int day) const
{
	Date tmp = *this;
	tmp -= day;
	return tmp;
}

//前置++
Date& Date::operator++()
{
	*this += 1;
	return *this;
}

// 后置++
// 增加这个int参数不是为了接收具体的值，仅仅是占位，跟前置++构成重载
Date Date::operator++(int)
{
	Date tmp = *this;
	*this += 1;

	return tmp;
}

//前置--
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}

//后置--
Date Date::operator--(int)
{
	Date tmp = *this;
	*this -= 1;

	return tmp;
}

//两个日期相减返回天数值
int Date::operator-(const Date& d) const
{
	Date max = *this;
	Date min = d;
	int flag = 1;

	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}

	int n = 0;
	while (min != max)
	{
		++min;
		++n;
	}

	return n * flag;
}

int main()
{
	Date d1(1949, 10, 1);
	Date d2(1949,10,1);
	cout<<d1.operator<=(d2)<<endl;
	//d1 += 100;
	d1 -= 100;
	return 0;
}

class Date
{
public:
	Date* operator&()
	{
		return this;
	}

	const Date* operator&()const
	{
		return this;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};